package jmine.tec.utils.uppercase;

import java.util.HashMap;
import java.util.Map;

/**
 * Implementacao de mapa que grava sempre todas as Strings (chave ou valor) em upperCase.
 * 
 * @param <K> Tipo da chave
 * @param <V> Tipo do valor armazenado
 * @author Rafael Volpato
 */
public class UpperCaseValueMap<K, V> extends HashMap<K, V> {

    private final Map<K, V> rawMap = new HashMap<K, V>();

    /**
     * Construtor.
     */
    public UpperCaseValueMap() {
        super();
    }

    /**
     * Construtor.
     * 
     * @param originalMap originalMap
     */
    public UpperCaseValueMap(Map<K, V> originalMap) {
        this.putAll(originalMap);

    }

    /**
     * Sobrecarrega o metodo put para gravar sempre valores em UpperCase.
     * 
     * @param key a chave do mapa
     * @param value o valor que deve ser gravado
     * @return o objeto que ja existia no mapa com a mesma chave ou <code>null</code>
     */
    @Override
    public V put(K key, V value) {
        // Guardar o valor original
        this.rawMap.put(key, value);

        // Salvar fazendo o upper-case.
        return super.put(key, this.getUpperCase(value));
    }

    /**
     * Retorna o valor associado a chave 'key' sem o tratamento upper-case.
     * 
     * @param key a chave do mapa
     * @return o valor associado a chave
     */
    public V getRaw(K key) {
        return this.rawMap.get(key);
    }

    /**
     * Se o objeto for uma {@link String} retorna a String em UpperCase.
     * 
     * @param obj objeto
     * @return Se o objeto for uma {@link String} retorna a String em UpperCase.
     */
    @SuppressWarnings("unchecked")
    private V getUpperCase(V obj) {
        if ((obj == null) || !(obj instanceof String)) {
            return obj;
        }
        return (V) ((String) obj).toUpperCase();
    }
}
